﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ITAP.ContourBuilder.Components;
using ITAP.ContourBuilder.Components.Dimensions;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace ITAP.ContourBuilder.Shapes
{
    public delegate void ShapeParameterChangedEventHandler();

    public class Shape
    {
        public event ShapeParameterChangedEventHandler BeforeShapeParameterChanging;
        public event ShapeParameterChangedEventHandler AfterShapeParameterChanging;

        protected ContourContainer baseContainer;

        public ContourContainer BaseContainer
        {
            get { return baseContainer; }
        }

        public void LoadBaseContainer(ContourContainer baseContainer)
        {
            this.baseContainer = baseContainer;
        }

        public void LoadBaseContainerFromStream(Stream stream)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            this.baseContainer = (ContourContainer)formatter.Deserialize(stream);          
        }

        public void SaveBaseContainerToStream(Stream stream)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, this.baseContainer);
        }

        /// <summary>
        /// Используются в перегрузке для каждого отдельного шейпа, чтобы шейп сам определял, где брать контейнер.
        /// </summary>
        public virtual void LoadBaseContainer()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Используются в перегрузке для каждого отдельного шейпа, чтобы шейп сам определял, куда сохранять контейнер.
        /// </summary>
        public virtual void SaveBaseContainer()
        {
            throw new NotImplementedException();
        }

        public void StartEnterParameter()
        {
            if (this.BeforeShapeParameterChanging != null)
                this.BeforeShapeParameterChanging.Invoke();
        }

        public void EndEnterParameter()
        {
            this.baseContainer.Update();
            if (this.AfterShapeParameterChanging != null)
                this.AfterShapeParameterChanging.Invoke();
        }

        public IContourComponent GetComponentById(int id)
        {
            IEnumerable<IContourComponent> allComponents = baseContainer.GetAllInnerComponents();
            foreach (IContourComponent component in allComponents)
                if (component.Id == id)
                    return component;

            return null;
        }

        public ContourConnector GetComponentByIdAsConnector(int id)
        {
            IEnumerable<IContourComponent> allComponents = baseContainer.GetAllInnerComponents();
            foreach (IContourComponent component in allComponents)
                if (component.Id == id)
                    return component as ContourConnector;

            return null;
        }

        public ContourElement GetComponentByIdAsElement(int id)
        {
            IEnumerable<IContourComponent> allComponents = baseContainer.GetAllInnerComponents();
            foreach (IContourComponent component in allComponents)
                if (component.Id == id)
                    return component as ContourElement;

            return null;
        }

        public Dimension GetComponentByIdAsDimension(int id)
        {
            IEnumerable<IContourComponent> allComponents = baseContainer.GetAllInnerComponents();
            foreach (IContourComponent component in allComponents)
                if (component.Id == id)
                    return component as Dimension;

            return null;
        }

        public ContourText GetComponentByIdAsText(int id)
        {
            IEnumerable<IContourComponent> allComponents = baseContainer.GetAllInnerComponents();
            foreach (IContourComponent component in allComponents)
                if (component.Id == id)
                    return component as ContourText;

            return null;
        }

        public ContourHole GetComponentByIdAsHole(int id)
        {
            IEnumerable<IContourComponent> allComponents = baseContainer.GetAllInnerComponents();
            foreach (IContourComponent component in allComponents)
                if (component.Id == id)
                    return component as ContourHole;

            return null;
        }

    }
}
